/** @file

Copyright (c) 2006-2023, Kunlun BIOS, Kunlun Technology (Beijing) Co., Ltd.. All
Rights Reserved.

You may not reproduce, distribute, publish, display, perform, modify, adapt,
transmit, broadcast, present, recite, release, license or otherwise exploit
any part of this publication in any form, by any means, without the prior
written permission of Kunlun Technology (Beijing) Co., Ltd..

Module Name:


Abstract:


Revision History:

**/

#include "Buzzer.h"

#include <Library/PostCodeLib.h>
#include <Library/ReportStatusCodeLib.h>
#include "PostCode.h"


#define CPU_WARNING  0x01
#define BOOT_WARNING  0x02

STATIC EFI_HII_HANDLE gStringPackHandle;

STATIC EFI_GUID mUiStringPackGuid = {
  0x35FE14C0, 0x8027, 0x80F2, {0x9B, 0x5E, 0x9D, 0x67, 0xA7, 0x20, 0xE0, 0x56}
};

//#define MCU_USE_MANUAL


typedef struct warn_alarm_fun{
    VOID (*Alarm)(UINTN ErrorType);
}WARN_ALARM_FUN_T;

/**

  To send cpld control.

  @param cmd

**/
VOID
SendCpldCtr(
  UINT32 cmd
  )
{
  UINT32 i;
  DEBUG((EFI_D_INFO, "send cmd to cpld : %d \n", cmd));
  //start
  MmioWrite32(PWR_CTR0_REG, 0x1);
  MicroSecondDelay(1000);
  for(i = 0; i < cmd; i++){
  MmioWrite32(PWR_CTR1_REG, 0x1);
  MicroSecondDelay(2000);
  MmioWrite32(PWR_CTR1_REG, 0x0);
  MicroSecondDelay(1000);
  }
  //end
  MicroSecondDelay(2000);
  MmioWrite32(PWR_CTR0_REG, 0x0);
}

/**

  Pull down.

  VOID

**/
VOID
Pulldown(
  VOID
  )
{

#if 1
  MmioWrite32(PWR_CTR1_REG, 0x0);
#endif

  MicroSecondDelay(100000);
}

/**

  To alarm cpld.

  @param ErrorType

**/
VOID
AlarmCpld(
  UINTN  ErrorType
  )
{
  MmioWrite32(PWR_CTR0_REG, 0x0);

  switch(ErrorType)
  {
    case ERROR_TYPE0:  //3 short 1 long
       SendCpldCtr(16);
       break;

  case ERROR_TYPE1:  //1 short 1 long
       SendCpldCtr(17);
       break;
  default:
      Pulldown();
    }
}

static WARN_ALARM_FUN_T warn_alarm_fun_cpld = {
  .Alarm = AlarmCpld
};

/**

  To alarm se.

  @param ErrorType

**/
VOID
AlarmSe(
  UINTN  ErrorType
  )
{

  switch(ErrorType)
  {

    case ERROR_TYPE0:  //3 short 1 long
      SendSeCtr(0x20);
      break;

    case ERROR_TYPE1:  //1 short 1 long
      SendSeCtr(0x21);
      break;

    case ERROR_TYPE2:  //4 short
      SendSeCtr(0x22);
      break;

    case ERROR_TYPE3:  //1 long 2 short
      SendSeCtr(0x23);
      DEBUG((EFI_D_ERROR,"No Graphics Card Found\n"));
      break;

    case ERROR_TYPE4:  //1 long 3 short
      SendSeCtr(0x24);
      DEBUG((EFI_D_ERROR,"GOP Initialization Failed\n"));
      break;

    case ERROR_TYPE5:  //2 long 1 short
      SendSeCtr(0x25);
      DEBUG((EFI_D_ERROR,"Don't Find A Hard Disk\n"));
      break;

    case ERROR_TYPE6:  //2 long 3 short
      SendSeCtr(0x26);
      DEBUG((EFI_D_ERROR,"USB Controller Abnomaly\n"));
      break;

    case ERROR_TYPE7:  //5 short
      SendSeCtr(0x27);
      break;

    default:
      Pulldown();
    }
}

static WARN_ALARM_FUN_T warn_alarm_fun_se = {
    .Alarm = AlarmSe
};

/**

  To get the flag.

  VOID

**/
void *
Get_flag (
  void
  )
{
    switch(pm_get_s3_flag_source())
    {
      case 0:
        return &warn_alarm_fun_cpld;
      case 2:
        return &warn_alarm_fun_se;
      default:
        return &warn_alarm_fun_cpld;
      }

}

/**

  Buzzer beep.

  @param ErrorType

**/
VOID
Buzzer_Beep(
  UINTN ErrorType
  )
{
  //pwr_ctr_fun_t *pwr_flag_p = get_flag_fun();
  WARN_ALARM_FUN_T *warn_alarm_fun_p;

  warn_alarm_fun_p = Get_flag();
  if(NULL == warn_alarm_fun_p || NULL == warn_alarm_fun_p->Alarm){
    while(1);
  }
  warn_alarm_fun_p->Alarm(ErrorType);
}

/**

  Initialize the string.

  VOID

**/
STATIC
VOID
InitializeStringSupport (
  VOID
  )
{
  gStringPackHandle = HiiAddPackages (
                         &mUiStringPackGuid,
                         gImageHandle,
                         BuzzerLibStrings,
                         NULL
                         );
  ASSERT (gStringPackHandle != NULL);
}

/**

  Uninitalize the String.

  VOID

**/
STATIC
VOID
UninitializeStringSupport (
  VOID
  )
{
  HiiRemovePackages (gStringPackHandle);
}

/**

  Display the setup wait information.

  @param InitPtr
  @param Num

**/
STATIC
VOID
EFIAPI
SetupWaitDisplay(
  UINT8* InitPtr,
  UINT8 Num
)
{
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black;
  EFI_GRAPHICS_OUTPUT_BLT_PIXEL White;
  EFI_STRING                    String;

  if ((gST->ConOut == NULL) || (InitPtr == NULL)) {
    return;
  }
  Black.Blue = 0;
  Black.Green = 0;
  Black.Red = 0;
  Black.Reserved = 0;

  White.Blue = 0xFF;
  White.Green = 0xFF;
  White.Red = 0xFF;
  White.Reserved = 0xFF;

  if (*InitPtr > 0) {
    gST->ConOut->EnableCursor(gST->ConOut, FALSE);
    gST->ConOut->ClearScreen(gST->ConOut);
    //[jckuang-0020]
    REPORT_STATUS_CODE(EFI_PROGRESS_CODE, BDS_DISPLAY_LOGO_SYSTEM_INFO);
    //[jckuang-0020]

   // EnableQuietBoot (PcdGetPtr(PcdLogoFile));

  if(Num == 1)
  {
    String = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_SETUP_PROMPT_ESC), NULL);
    ASSERT (String != NULL);
    PrintXY(20, 580, &White, &Black, String);
    FreePool (String);
  }
  else
  {
    String = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_SETUP_PROMPT_ANY), NULL);
    ASSERT (String != NULL);
    PrintXY(20, 20, &White, &Black, String);
    FreePool (String);
  }
    *InitPtr = 0;
  }

}

/**

  Prompt setup wait information.

  VOID

**/
VOID
SetupPromptWait_Boot(

 )
{
  UINT8                           InitFlag;
  EFI_INPUT_KEY                   Key;
  EFI_BOOT_MANAGER_LOAD_OPTION    BootManagerMenu;

  InitFlag = 1;
  InitializeStringSupport();
    Buzzer_Beep(ERROR_TYPE4);
    while (1)
   {
     SetupWaitDisplay(&InitFlag,BOOT_WARNING);
      gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
       EfiBootManagerGetBootManagerMenu (&BootManagerMenu);
    if((Key.ScanCode != 0)||(Key.UnicodeChar != 0))
    {
       DEBUG((EFI_D_INFO, "Key.ScanCode=0x%x,FUNCTION=%a line = %d\n",Key.ScanCode, __FUNCTION__,__LINE__));
       EfiBootManagerBoot (&BootManagerMenu);
    }

   }
    UninitializeStringSupport();
}

/**

  Prompt setup wait.

  VOID

**/
VOID
SetupPromptWait_CpuFan(
 )
{
  EFI_INPUT_KEY      Key;
  UINT8              InitFlag;
  InitializeStringSupport();

  InitFlag = 1;
    while (1)
   {
     SetupWaitDisplay(&InitFlag,CPU_WARNING);
      gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
     // DEBUG((EFI_D_INFO, "Key.ScanCode=0x%x,FUNCTION=%a line = %d\n",Key.ScanCode, __FUNCTION__,__LINE__));
     if(Key.ScanCode==SCAN_ESC)
      {
        break;
      }
   }
    UninitializeStringSupport();
}



